package com.xueyi.common.core.utils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author gaorongyi
 */
public class MapUtil {
    /**
     * {@link java.util.Map}默认初始大小
     */
    public static final int MAP_DEFAULT_SIZE = 16;

    /**
     * {@link java.util.Map}默认负载因子
     */
    public static final double MAP_DEFAULT_LOADER_FACTOR = 0.75;

    /**
     * 根据map需要存储的数据集大小计算Map的初始值
     *
     * @param predictSize 需要存储的数据集大小
     * @return map的capacity值
     */
    public static int getMapCapacity(int predictSize) {
        return BigDecimal.valueOf(predictSize).divide(BigDecimal.valueOf(MAP_DEFAULT_LOADER_FACTOR), RoundingMode.HALF_UP).intValue() + 1;
    }

    /**
     * 初始化默认HashMap
     */
    public static <K, V> HashMap<K, V> initHashMap() {
        return new HashMap<>(MAP_DEFAULT_SIZE);
    }

    /**
     * 初始化默认ConcurrentHashMap
     */
    public static <K, V> ConcurrentHashMap<K, V> initConcurrentHashMap() {
        return new ConcurrentHashMap<>(MAP_DEFAULT_SIZE);
    }

    /**
     * 初始化指定数据集大小的HashMap
     *
     * @param predictSize 需要存储的数据集大小
     */
    public static <K, V> HashMap<K, V> initHashMap(int predictSize) {
        return new HashMap<>(getMapCapacity(predictSize));
    }

    /**
     * 初始化指定数据集大小的ConcurrentHashMap
     *
     * @param predictSize 需要存储的数据集大小
     */
    public static <K, V> ConcurrentHashMap<K, V> initConcurrentHashMap(int predictSize) {
        return new ConcurrentHashMap<>(getMapCapacity(predictSize));
    }

    /**
     * 初始化指定数据集大小的LinkedHashMap
     *
     * @param predictSize 需要存储的数据集大小
     */
    public static <K, V> HashMap<K, V> initLinkedHashMap(int predictSize) {
        return new LinkedHashMap<>(getMapCapacity(predictSize));
    }
}